package com.example.adminserivce.Service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.adminserivce.Mapper.ActivityMapper;
import com.example.adminserivce.Service.ActivityService;
import com.example.adminserivce.Service.UserService;
import com.example.adminserivce.domain.Vo.ActivityStatistics;
import com.example.common.constants.ActivityConstants;
import com.example.common.constants.OtherConstants;
import com.example.common.constants.RdsConstants;
import com.example.common.constants.RoleConstants;
import com.example.common.domain.pojo.Activity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity> implements ActivityService {
    // 基准日期：2025-05-20 为第一周起始日
    private static final LocalDate BASE_DATE = LocalDate.of(OtherConstants.ACTIVE_YEAR,
            OtherConstants.ACTIVE_MONTH, OtherConstants.ACTIVE_DAY);//年，月，日
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private UserService userService;
    @Autowired
    private ActivityMapper ActivityMapper;

    @Override
    public ActivityStatistics getWeeklyActivity(String userType, LocalDate targetDate) {
        // 1. 处理日期参数（为空时默认当前日期）
        LocalDate date = targetDate != null ? targetDate : LocalDate.now();
        // 2. 计算周次
        int weekNumber = calculateWeekNumber(date);
        // 3. 构建Redis键
//        String activeKey = String.format("%s:active:week:%d", userType, weekNumber);
//        String moduleKeyPattern = String.format("%s:module:week:%d:*", userType, weekNumber);
        String activeKey = String.format(RdsConstants.WEEKLY_ACTIVE_KEY, userType, weekNumber);
        String moduleKeyPattern = String.format(RdsConstants.USER_MODULE_KEY, userType, weekNumber);
        // 4. 获取活跃用户数
        Long activeCount = redisTemplate.opsForHyperLogLog().size(activeKey);

        // 5. 获取总用户数
        Long totalCount = userType.equals(RoleConstants.TEACHER)
                ? userService.getTotalTeacherCount()  //是老师则调用这个方法，获取老师总数
                : userService.getTotalStudentCount();

        // 6. 获取模块分布
        Map<String, Long> moduleDistribution = getModuleDistribution(moduleKeyPattern);
        // 7. 构建结果
        return new ActivityStatistics(
                activeCount,
                totalCount,
                calculatePercentage(activeCount, totalCount),
                moduleDistribution
        );
    }

    /**
     * 查询指定日期范围内的日活跃度统计
     *
     * @param userType  用户类型（teacher/student）
     * @param startDate 开始日期（包含）
     * @param endDate   结束日期（包含）
     * @return 日活跃度列表
     */
    public List<Activity> getDailyActivityByDateRange(
            String userType,
            LocalDate startDate,
            LocalDate endDate
    ) {
        LambdaQueryWrapper<Activity> query = new LambdaQueryWrapper<>();
        query.eq(Activity::getUserType, userType)
                .ge(Activity::getDate, startDate) // 大于等于开始日期
                .le(Activity::getDate, endDate)   // 小于等于结束日期
                .orderByAsc(Activity::getDate);    // 按日期升序排列

        return ActivityMapper.selectList(query);
    }

    // 计算周次（从基准日期开始的周数）
    public int calculateWeekNumber(LocalDate date) {
        long daysDiff = ChronoUnit.DAYS.between(BASE_DATE, date);
        return (int) (daysDiff / 7) + 1;
    }


    // 计算百分比
    public Double calculatePercentage(Long activeCount, Long totalCount) {
        if (totalCount == 0) return 0.0;
        return Math.round((activeCount.doubleValue() / totalCount) * 10000) / 100.0; // 保留两位小数
    }

    // 获取模块分布统计
    public Map<String, Long> getModuleDistribution(String userType, String date) {
        Map<String, Long> distribution = new HashMap<>();
//        String pattern = userType + ":module:*:" + date;
        String pattern = userType + ActivityConstants.MODULE_STATISTICS + date;
        redisTemplate.keys(pattern).forEach(key -> {
            Map<Object, Object> userModules = redisTemplate.opsForHash().entries(key);
            userModules.forEach((module, count) -> {
                // 获取当前模块的累计值（默认为0）,将新的计数转换为Long并累加,更新模块统计
                String moduleName = module.toString();
                Long moduleCount = Long.parseLong(count.toString());
                // 使用 compute 方法安全地更新计数
                distribution.compute(moduleName, (k, v) -> (v == null ? moduleCount : v + moduleCount));
            });
        });
        return distribution;
    }

    // 获取模块分布统计
    public Map<String, Long> getModuleDistribution(String patternKey) {
        Map<String, Long> distribution = new HashMap<>();
        redisTemplate.keys(patternKey).forEach(key -> {
            Map<Object, Object> userModules = redisTemplate.opsForHash().entries(key);
            userModules.forEach((module, count) -> {
                // 获取当前模块的累计值（默认为0）,将新的计数转换为Long并累加,更新模块统计
                String moduleName = module.toString();
                Long moduleCount = Long.parseLong(count.toString());
                // 使用 compute 方法安全地更新计数
                distribution.compute(moduleName, (k, v) -> (v == null ? moduleCount : v + moduleCount));
            });
        });
        return distribution;
    }
}
